package com.atguigu.tingshu.payment.service.impl;

import com.atguigu.tingshu.payment.config.WxPayV3Config;
import com.atguigu.tingshu.payment.context.PaymentStrategyContext;
import com.atguigu.tingshu.payment.service.PaymentInfoService;
import com.atguigu.tingshu.payment.service.WxPayService;
import com.atguigu.tingshu.payment.util.PayUtil;
import com.atguigu.tingshu.vo.payment.WeChatPayVo;
import com.google.common.collect.Lists;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum;
import com.wechat.pay.java.service.payments.model.Transaction.TradeTypeEnum;
import com.wechat.pay.java.service.payments.model.TransactionAmount;
import com.wechat.pay.java.service.payments.model.TransactionPayer;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

	@Autowired
	private PaymentInfoService paymentInfoService;
	@Autowired
	private WxPayV3Config wxPayV3Config;
	// PaymentStrategy
	@Override
	public WeChatPayVo createJsapi(String paymentType, String orderNo) {
		// 策略模式进行业务调用
		return PaymentStrategyContext.getPaymentStrategy(paymentType).createJsapi(paymentType, orderNo);
	}

	@Override
	public Boolean queryPayStatus(String orderNo) {
		// 构造发送对象
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(wxPayV3Config.getConfig()).build();
		QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
		queryRequest.setOutTradeNo(orderNo);
		queryRequest.setMchid(wxPayV3Config.merchantId);
		try {
			// TODO: 现在不能喝发消息,下面 transaction 对象是虚拟的
			// Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
			Transaction transaction = new Transaction();
			TransactionAmount transactionAmount = new TransactionAmount();
			transactionAmount.setTotal(1);
			transaction.setAmount(transactionAmount);
			transaction.setAppid(wxPayV3Config.getAppid());
			transaction.setMchid(wxPayV3Config.getMerchantId());
			transaction.setOutTradeNo(orderNo);
			transaction.setPayer(new TransactionPayer());
			transaction.setPromotionDetail(Lists.newArrayList());
			transaction.setSuccessTime(String.valueOf(new Date().getTime()));
			transaction.setTradeState(TradeStateEnum.SUCCESS);
			transaction.setTradeStateDesc("SUCCESS");
			transaction.setTradeType(TradeTypeEnum.JSAPI);
			transaction.setTransactionId("SUCCESS");
			Transaction.TradeStateEnum tradeState = transaction.getTradeState();
			if(Transaction.TradeStateEnum.SUCCESS.equals(tradeState)){
				paymentInfoService.updatePaymentStatus(transaction);
				return true;
			}else {
				return false;
			}
		} catch (ServiceException e) {
			// API返回失败, 例如ORDER_NOT_EXISTS
			System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
			System.out.printf("reponse body=[%s]\n", e.getResponseBody());
		}
		return true;
	}

	@Override
	public void notificationFunc(HttpServletRequest httpServletRequest) {
	// 	从 httpServletRequest 获取数据解析
		String wechatSignature = httpServletRequest.getHeader("Wechatpay-Signatur");
		String wechatPaySerial = httpServletRequest.getHeader("Wechatpay-Serial");
		String wechatpayNonce = httpServletRequest.getHeader("Wechatpay-Nonce");
		String wechatTimestamp = httpServletRequest.getHeader("Wechatpay-Timestamp");
		String requestBody = PayUtil.readData(httpServletRequest);
		// 构造 RequestParam
		RequestParam requestParam = new RequestParam.Builder()
				.serialNumber(wechatPaySerial)
				.nonce(wechatpayNonce)
				.signature(wechatSignature)
				.timestamp(wechatTimestamp)
				.body(requestBody)
				.build();

		// 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
		// 初始化 NotificationParser
		NotificationParser parser = new NotificationParser(wxPayV3Config.getConfig());
		// 以支付通知回调为例，验签、解密并转换成 Transaction
		Transaction transaction = parser.parse(requestParam, Transaction.class);
		if(Objects.nonNull(transaction)){
			TradeStateEnum tradeState = transaction.getTradeState();
			if(TradeStateEnum.SUCCESS.equals(tradeState)){
				paymentInfoService.updatePaymentStatus(transaction);
			}
		}
	}


}
